#include "ftpAccessManager.h"

ftpAccessManager::ftpAccessManager(QObject *parent)
    : QObject{parent}
{
    murl.setScheme("ftp"); // 设置协议
}

/*
 * 设置FTP主机地址信息，包括Ip地址和端口号
*/
void ftpAccessManager::setHostPortInfo(const QString &host, quint16 prot)
{
    murl.setHost(host);
    murl.setPort(prot);

}

/*
 * 设置FTP用户密码信息
*/
void ftpAccessManager::setUserPwdInfo(const QString &userName, const QString &pwd)
{
    murl.setUserName(userName);
    murl.setPassword(pwd);
}

/*
 * 上传文件
 * 参数1:本地文件(带路径)    参数2：服务器端文件(带路径) <服务器路径必须带上文件名，不然服务器不知道写什么样的文件>
*/
void ftpAccessManager::putFileFromClent(const QString &clientFile, const QString &serverPath)
{
    putFileData = new QFile(clientFile, this);
    QString serverFileNamePath = serverPath + "/" +
            QFileInfo(clientFile).fileName(); //路径+文件拼接,保证服务器端写入的文件和本地文件同名

    //step1 :: setUrl
    murl.setPath(serverFileNamePath);

    //step2:打开文件 把文件读入到网络流发出去
    if(putFileData->open(QIODevice::ReadOnly))
    {
        //step3:upload 上传
        putNetReply = mNetAccMgr.put(QNetworkRequest(murl), putFileData);

        //step4:关联信号与槽
        connect(putNetReply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgressSlot(qint64, qint64)));
        connect(putNetReply, SIGNAL(finished()), this, SLOT(uploadFinishedSlot()));
        connect(putNetReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(uploadErrorSlot(QNetworkReply::NetworkError)));
    }
    else
    {
        delete putFileData;
        putFileData = nullptr;
    }
}

/*
 * 下载文件
 * 参数1:需要写入的本地文件(带路径 不带路径则为当前目录)    参数2：服务器端的路径
*/
void ftpAccessManager::getFileFromServer(const QString &saveNameWithPath, const QString &downloadPath)
{
    getFileData = new QFile(saveNameWithPath, this);

    //step1 :: setUrl
    murl.setPath(downloadPath);

    if(getFileData->open(QIODevice::WriteOnly | QFile::Truncate))
    {
        getNetReply = mNetAccMgr.get(QNetworkRequest(murl));
        //step4 :
        connect(getNetReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgressSlot(qint64, qint64)));
        connect(getNetReply, SIGNAL(finished()), this, SLOT(downloadFinishedSlot()));
        connect(getNetReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadErrorSlot(QNetworkReply::NetworkError)));
    }
    else
    {
        delete getFileData;
        getFileData = nullptr;
    }
}


void ftpAccessManager::uploadProgressSlot(qint64 bytesSent, qint64 bytesTotal)
{
    emit uploadProgressSignal(bytesSent, bytesTotal);
    //qDebug() << "uploadProgressSlot" << bytesSent << bytesTotal;
}



void ftpAccessManager::uploadFinishedSlot()
{
    qDebug() << "uploadFinishedSlot" ;

    putNetReply->deleteLater();
    delete putFileData;
    putFileData = nullptr;
}

void ftpAccessManager::uploadErrorSlot(QNetworkReply::NetworkError errorCode)
{
    putNetReply->deleteLater();
    delete putFileData;
    putFileData = nullptr;

    switch (errorCode)
    {
    case QNetworkReply::HostNotFoundError :
        qDebug() << "HostNotFoundError";
        break;
    case QNetworkReply::ConnectionRefusedError :
        qDebug() << "ConnectionRefusedError";
        break;
    default:
        qDebug() << "orther error" << errorCode;
        break;
    }

    emit netErrorSignal(errorCode);
}

void ftpAccessManager::downloadProgressSlot(qint64 bytesSent, qint64 bytesTotal)
{

    emit downloadProgressSignal(bytesSent, bytesTotal);
    getFileData->write(getNetReply->readAll());         //写文件到磁盘
}


void ftpAccessManager::downloadFinishedSlot()
{
    qDebug() << "downloadFinishedSlot";

    getNetReply->deleteLater();
    delete getFileData;
    getFileData = nullptr;
}

void ftpAccessManager::downloadErrorSlot(QNetworkReply::NetworkError errorCode)
{
    qDebug() << "downloadErrorSlot" << errorCode;

    getNetReply->deleteLater();
    delete getFileData;
    getFileData = nullptr;

    emit netErrorSignal(errorCode);
}

/* 演示deleteLater什么时候生效 */
bool ftpAccessManager::event(QEvent *event)
{
    qDebug()<<"event" << event->isAccepted();
    return true;
}
